package fileUtil

import (
	"archive/zip"
	"errors"
	"github.com/axgle/mahonia"
	"io"
	"log"
	"os"
	"os/exec"
	"path"
	"path/filepath"
	"runtime"
	"strings"
)

/**
文件是否存在
*/
func PathExists(path string) bool {
	_, err := os.Stat(path)
	if err == nil {
		return true
	}
	return os.IsExist(err)
}

/*
获取当前文件的目录
*/
func GetCurrentPath() string {
	file, err := exec.LookPath(os.Args[0])
	if err != nil {
		panic(err)
	}
	path, err := filepath.Abs(file)
	if err != nil {
		panic(err)
	}
	if runtime.GOOS == "windows" {
		path = strings.Replace(path, "\\", "/", -1)
	}
	//fmt.Println("path222:", path)
	i := strings.LastIndex(path, "/")
	if i < 0 {
		panic(errors.New(`Can't find "/" or "\".`))
	}
	//fmt.Println("path333:", path)
	return string(path[0 : i+1])
}

/**
转换编码格式
*/
func ConvertToString(src string, srcCode string, tagCode string) string {
	srcCoder := mahonia.NewDecoder(srcCode)
	srcResult := srcCoder.ConvertString(src)
	tagCoder := mahonia.NewDecoder(tagCode)
	_, cdata, _ := tagCoder.Translate([]byte(srcResult), true)
	result := string(cdata)
	return result
}

//拷贝文件 form 目标文件 to 目标文件夹
func CopyDir(form string, to string) error {
	form = path.Clean(form) + "/"
	to = path.Clean(to) + "/"
	//form = strings.Replace(strings.Replace(form, "\\", "/", -1), "//", "/", -1)
	//to = strings.Replace(strings.Replace(to, "\\", "/", -1), "//", "/", -1)
	if !PathExists(form) {
		return errors.New("起始文件不存在")
	}
	fileInfo, err := os.Stat(form)
	if err != nil {
		return err
	}
	name := fileInfo.Name()
	s := to + name
	if PathExists(s) {
		err := os.RemoveAll(to + name)
		if err != nil {
			return err
		}
	}
	formSuffix := strings.TrimSuffix(form, name+"/")

	err = filepath.Walk(form, func(thisPath string, f os.FileInfo, err error) error {
		if f == nil {
			return err
		}
		thisPath = path.Clean(thisPath)
		formSuffix = strings.Replace(path.Clean(formSuffix), "/", "\\", -1)
		s := strings.Replace(thisPath, formSuffix, "", 1)
		if f.IsDir() {
			if formSuffix != thisPath {
				os.MkdirAll(to+s, os.ModePerm)
			}
		} else {
			suffix := strings.TrimSuffix(s, f.Name())
			_, err := CopyFile(thisPath, to+suffix)
			if err != nil {
				return err
			}

		}
		return nil
	})
	return err
}

//复制文件
func CopyFile(form, to string) (int64, error) {
	srcFile, err := os.Open(form)
	if err != nil {
		return 0, err
	}
	defer srcFile.Close()
	fileInfo, _ := os.Stat(form)
	name := fileInfo.Name()
	toFile := to + "/" + name
	suffix := strings.TrimSuffix(toFile, name)
	if !PathExists(suffix) {
		err := os.MkdirAll(suffix, os.ModePerm)
		if err != nil {
			return 0, nil
		}
	}
	dstFile, err := os.Create(toFile)
	if err != nil {
		return 0, nil
	}
	defer dstFile.Close()
	return io.Copy(dstFile, srcFile)
}

//压缩文件
func ZipDir(dir, zipFile string) error {
	dir = path.Clean(dir)
	fz, err := os.Create(zipFile)
	if err != nil {
		return err
	}
	defer fz.Close()

	w := zip.NewWriter(fz)
	defer w.Close()
	return filepath.Walk(dir, func(path string, info os.FileInfo, err error) error {
		if !info.IsDir() {
			s := path[len(dir)+1:]
			fDest, err := w.Create(s)
			if err != nil {
				return err
			}
			fSrc, err := os.Open(path)
			if err != nil {
				return err
			}
			defer fSrc.Close()
			_, err = io.Copy(fDest, fSrc)
			if err != nil {

				return err
			}
		}
		return nil
	})
}

//解压文件
func unzipDir(zipFile, dir string) error {

	r, err := zip.OpenReader(zipFile)
	if err != nil {
		return err
	}
	defer r.Close()

	for _, f := range r.File {
		func() {
			path := dir + string(filepath.Separator) + f.Name
			os.MkdirAll(filepath.Dir(path), 0755)
			fDest, err := os.Create(path)
			if err != nil {
				log.Printf("Create failed: %s\n", err.Error())
				return
			}
			defer fDest.Close()

			fSrc, err := f.Open()
			if err != nil {
				log.Printf("Open failed: %s\n", err.Error())
				return
			}
			defer fSrc.Close()

			_, err = io.Copy(fDest, fSrc)
			if err != nil {
				log.Printf("Copy failed: %s\n", err.Error())
				return
			}
		}()
	}
	return nil
}
